﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GoBangController_Robot : IGoBangController
{
    private static GoBangController_Robot m_Inst;
    public static GoBangController_Robot Instance
    {
        get
        {
            if (null == m_Inst)
                m_Inst = new GoBangController_Robot();
            return m_Inst;
        }
    }

    private GoBangTest m_View;

    private float m_AIDownCheckLeftTime = 5;

    public void OnDestroy()
    {
    }

    public void OnEnable(GoBangTest view)
    {
        m_View = view;

        m_View.m_MyChessColor = 1;
        m_View.m_TxtServerName.text = "黑棋(自己)";
        m_View.m_TxtClientName.text = "白棋(机器人)";
        m_View.m_BtnReady.gameObject.SetActive(false);

        OnWaitStart();
    }

    public void OnDisable()
    {
    }
    

    public void OnWaitStart()
    {
        m_View.m_Status = 1;
        m_View.UpdateTurnHint();
    }

    public void OnDownChess(int turnFlag, int row, int col)
    {

    }

    public void OnUpdate()
    {
        AIDownCheckUpdate();
    }

    public void OnLeftTimeUp()
    {
        m_AIDownCheckLeftTime = UnityEngine.Random.Range(3, 5);
        //todo: 超过时间没落子, 就随机落子
        if (m_View.IsMyTurn())
            MyAutoDownChess();
        else
            AIDownChess();
    }

    public void OnNextTurn()
    {
        m_AIDownCheckLeftTime = UnityEngine.Random.Range(3, 5);
    }

    private void MyAutoDownChess()
    {
        if (0 == m_View.m_ChessCount)
        {
            m_View.DownChess(m_View.m_GridNum / 2, m_View.m_GridNum / 2);
            return;
        }

        //在上一步的边上落子
        if (-1 != m_View.m_LastChessDownRow)
        {
            for (int i = 1; i < m_View.m_GridNum; ++i)
            {
                var list = GetAroundEmptyList(m_View.m_LastChessDownRow, m_View.m_LastChessDownCol, i);
                Debug.Log($"MyAutoDownChess: expandNum:{i}, last:{m_View.m_LastChessDownRow}*{m_View.m_LastChessDownCol}, aroundNum:{list.Count}");
                if (list.Count > 0)
                {
                    int index = UnityEngine.Random.Range(0, list.Count);
                    var gridInfo = list[index];
                    m_View.DownChess(gridInfo.x, gridInfo.y);
                    break;
                }
            }
        }
    }


    //******************** AI

    //轮到AI时, AI落子倒计时
    private void AIDownCheckUpdate()
    {
        if (m_View.m_TurnFlag == m_View.m_MyChessColor) return;

        float leftTime = m_AIDownCheckLeftTime - Time.deltaTime;
        m_AIDownCheckLeftTime = leftTime;
        if (leftTime <= 0)
        {
            AIDownChess();
        }
    }

    private List<Vector2Int> m_TempList = new List<Vector2Int>();
    private List<Vector2Int> GetAroundEmptyList(int row, int col, int expandNum = 1)
    {
        m_TempList.Clear();

        int rowSign = 1;
        for (int i = 0; i < 1; ++i) //正负各一次
        {
            int rowTemp = row + rowSign * expandNum;
            if (rowTemp < 0 || rowTemp >= m_View.m_GridNum) continue;

            int colSign = 1;
            for (int j = 0; j < 1; ++j) //正负各一次
            {
                int colTemp = col + colSign * expandNum;
                if (colTemp < 0 || colTemp >= m_View.m_GridNum) continue;

                if (0 == m_View.m_GridChess[rowTemp][colTemp])
                {
                    m_TempList.Add(new Vector2Int(colTemp, rowTemp));
                }
                colSign = -colSign;
            }
            rowSign = -rowSign;
        }

        return m_TempList;
    }

    private bool IsAroundHaveEmpty(int row, int col, int expandNum = 1)
    {
        int rowSign = 1;
        for (int i = 0; i < 1; ++i) //正负各一次
        {
            int rowTemp = row + rowSign * expandNum;
            if (rowTemp < 0 || rowTemp >= m_View.m_GridNum) continue;

            int colSign = 1;
            for (int j = 0; j < 1; ++j) //正负各一次
            {
                int colTemp = col + colSign * expandNum;
                if (colTemp < 0 || colTemp >= m_View.m_GridNum) continue;

                if (0 == m_View.m_GridChess[rowTemp][colTemp])
                    return true;

                colSign = -colSign;
            }
            rowSign = -rowSign;
        }

        return false;
    }

    private void AIDownChess()
    {
        if (0 == m_View.m_ChessCount)
        {
            m_View.DownChess(m_View.m_GridNum / 2, m_View.m_GridNum / 2);
        }
        else if (1 == m_View.m_ChessCount)
        {
            int row = m_View.m_GridNum / 2;
            int col = row;
            if (0 == m_View.m_GridChess[row][col])
            {
                m_View.DownChess(row, col);
            }
            else
            {
                var list = GetAroundEmptyList(row, col);
                int index = UnityEngine.Random.Range(0, list.Count);
                var gridInfo = list[index];
                m_View.DownChess(gridInfo.x, gridInfo.y);
            }
        }
        else
        {
            //找一个最佳落子点
            int downRow = -1;
            int downCol = -1;
            int maxScore = -1;
            for (int row = 0; row < m_View.m_GridNum; ++row)
            {
                for (int col = 0; col < m_View.m_GridNum; ++col)
                {
                    if (0 == m_View.m_GridChess[row][col] && IsAroundHaveEmpty(row, col))
                    {
                        m_View.m_GridChess[row][col] = m_View.m_MyChessColor;

                        AIEvaluate(row, col, m_View.m_MyChessColor, out var myScore);
                        AIEvaluate(row, col, 3 - m_View.m_MyChessColor, out var otherScore);
                        int score = myScore + otherScore;
                        if (score > maxScore)
                        {
                            Debug.Log($"AIMaxEvaluate: r*c:{row},{col}: my:{myScore}, other:{otherScore}");
                            maxScore = score;
                            downRow = row;
                            downCol = col;
                        }

                        m_View.m_GridChess[row][col] = 0;
                    }
                }
            }
            if (-1 == downRow || -1 == downCol)
            {
                Debug.LogWarning($"-1 ??? rxc: {downRow}, {downCol}");
            }
            else
            {
                m_View.DownChess(downRow, downCol);
            }
        }
    }

    //评估在这个位置落子的好坏(用一个分数来评判)
    private bool AIEvaluate(int row, int col, int chessColor, out int score)
    {
        int[,] scoreLookupTable = new int[,] {
            {0, 1, 100, 1000, 10000, 1000000},
            {0, 0, 100, 100, 900, 1000000},
            {0, 0, 0, 0, 0, 1000000},
        };

        score = 0;
        int[] xDir = new int[] { 1, 0, 1, -1 }; //对应: 水平, 垂直, 对角1, 对角2
        int[] yDir = new int[] { 0, 1, 1, 1 };
        for (int i = 0; i < xDir.Length; ++i)
        {
            int num = m_View.CheckSameChessColorNum(chessColor, row, col, xDir[i], yDir[i], out var emptyBreakNum);
            if (num >= 4)
            {
                score = scoreLookupTable[0, 5];
                return true;
            }
            score += scoreLookupTable[2 - emptyBreakNum, num + 1];
        }

        return false;
    }

    //********************

}
